package com.ztools.pc.provider;

import cn.hutool.core.util.StrUtil;
import com.ztools.api.service.pc.PcPayService;
import com.ztools.api.service.wx.WxMsgService;
import com.ztools.common.model.pc.coupon.CouponRecord;
import com.ztools.common.model.pc.information.InformationPoint;
import com.ztools.common.model.pc.information.WeChatMember;
import com.ztools.common.model.pc.store.Commodity;
import com.ztools.common.model.pc.store.OnlineStock;
import com.ztools.common.model.pc.store.StoreSale;
import com.ztools.common.model.wx.payment.Cart;
import com.ztools.common.model.wx.payment.CartItem;
import com.ztools.common.util.common.Result;
import com.ztools.common.util.common.enumUnit.CouponUsedRouteEnum;
import com.ztools.common.util.common.enumUnit.PaymentTypeEnum;
import com.ztools.common.util.common.enumUnit.PointChannelEnum;
import com.ztools.common.util.common.templates.SaleTemplate;
import com.ztools.common.util.pc.RedisUtil;
import com.ztools.pc.async.CouponAsync;
import com.ztools.pc.async.StoreAsync;
import com.ztools.pc.service.coupon.CouponRecordService;
import com.ztools.pc.service.information.InformationPointService;
import com.ztools.pc.service.information.MemberService;
import com.ztools.pc.service.store.CommodityService;
import com.ztools.pc.service.store.OnlineStockService;
import com.ztools.pc.service.store.StoreSaleService;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author: seeTools
 * @Date: 2023/6/3  21:40
 * @Version 1.0
 */
@Service(version = "1.0", timeout = 3000)
public class PcPayServiceImpl implements PcPayService {

    @Resource
    private StoreSaleService storeSaleService;
    @Resource
    private CommodityService commodityService;
    @Resource
    private MemberService memberService;
    @Resource
    private CouponAsync couponAsync;
    @Resource
    private StoreAsync storeAsync;
    @Resource
    private InformationPointService informationPointService;
    @Resource
    private CouponRecordService couponRecordService;
    @Resource
    private OnlineStockService onlineStockService;
    @Resource
    private SaleTemplate saleTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Reference(version = "1.0", check = false, timeout = 6000)
    private WxMsgService wxMsgService;


    @Override
    public Result validateOnlineStockCart(Cart cart) {
        if (cart.getMemberId() != null) {
            WeChatMember member = memberService.getById(cart.getMemberId());
            // 1.判断会员积分是否足够
            if (PaymentTypeEnum.POINT.getPaymentType().equals(cart.getPaymentType())) {
                if (member.getTotalPoints() < cart.getPoint()) {
                    return Result.error("会员积分不够");
                }
            }
            if (PaymentTypeEnum.POINT_PLUS_MONEY.getPaymentType().equals(cart.getPaymentType())) {
                if (member.getTotalPoints() < cart.getPayAmount().intValue()) {
                    return Result.error("会员积分不够");
                }
            }
            // 2.判断商品库存是否足够
            List<CartItem> cartList = cart.getCartList();
            for (CartItem cartItem : cartList) {
                List<OnlineStock> onlineStockList = onlineStockService.findBy("commodity_id", cartItem.getId());
                OnlineStock onlineStock = onlineStockList.get(0);
                if (onlineStock.getOnlineNumber() == 0) {
                    return Result.error("商品被枪光了，去看看其他商品叭！！");
                }
                if (onlineStock.getOnlineNumber() < cartItem.getNums()) {
                    return Result.error("暂时没有这么多的商品哟！！！");
                }
            }
        }
        return Result.success();
    }

    @Override
    public Result save(Cart cart) {
        stringRedisTemplate.opsForValue().increment(RedisUtil.QUERY_ORDER_NUMBER + cart.getPaymentNo());
        WeChatMember member = memberService.getById(cart.getMemberId());
        ArrayList<CouponRecord> couponRecordList = new ArrayList<>();
        // 1.生成结算记录
        List<StoreSale> storeSaleList = getStoreSale(cart);
        if (storeSaleList.size() > 0) {
            storeSaleService.saveBatch(storeSaleList);
        }
        // 2.更新会员基本信息
        setMemberSale(cart, member);
        memberService.update(member);
        // 3.扣除会员积分
        if (PaymentTypeEnum.POINT.getPaymentType().equals(cart.getPaymentType())
                || PaymentTypeEnum.POINT_PLUS_MONEY.getPaymentType().equals(cart.getPaymentType())) {
            InformationPoint informationPoint = InformationPoint.builder()
                    .memberId(cart.getMemberId())
                    .channel(PointChannelEnum.STORE.getChannel())
                    .channelId(cart.getPaymentNo())
                    .operationPoints(cart.getPoint())
                    .build();
            if (PaymentTypeEnum.POINT.getPaymentType().equals(cart.getPaymentType())) {
                informationPoint.setOperationPoints(cart.getPayAmount().intValue());
            }
            informationPointService.reduce(informationPoint);
        }
        // 4.扣除会员优惠券
        if (StrUtil.isNotEmpty(cart.getCouponIds())) {
            String[] couponIdArray = cart.getCouponIds().split(",");
            for (String id : couponIdArray) {
                CouponRecord couponRecord = CouponRecord.builder()
                        .id(Long.parseLong(id))
                        .memberId(member.getId())
                        .build();
                couponRecordList.add(couponRecord);
            }
            // 物理删除可用券里面的数据
            couponRecordService.deleteBatch(couponRecordList);
            // 使用优惠券
            couponAsync.useCoupons(member.getId(), CouponUsedRouteEnum.STORE, cart.getTemplateIds());
            // 刷新会员券包
            couponAsync.refreshPacket(member.getId());
        }
        // 5.扣除商品库存
        storeAsync.storeSale(cart);
        // 发送微信客服消息
        wxMsgService.sendKeFuMessage(member.getOpenid(), saleTemplate.storeSaleTemplate(cart));
        return Result.success();
    }


    /**
     * 获取销售数据
     *
     * @param cart cart
     */
    public List<StoreSale> getStoreSale(Cart cart) {
        List<CartItem> cartList = cart.getCartList();
        List<StoreSale> storeSaleList = new ArrayList<>();
        // 订单金额单位为分所以/100
        cart.setPayAmount(cart.getPayAmount().divide(new BigDecimal(100)));
        Date date = new Date();
        if (cartList.size() > 0) {
            for (CartItem cartItem : cartList) {
                Commodity commodity = commodityService.getById(cartItem.getId());
                StoreSale storeSale = new StoreSale();
                storeSale.setPaymentNo(cart.getPaymentNo());
                storeSale.setCommodityId(cartItem.getId());
                storeSale.setAmount(cart.getAmount());
                storeSale.setPayAmount(cart.getPayAmount());
                storeSale.setPayDate(date);
                storeSale.setPayType(cart.getPaymentType());
                storeSale.setCouponIds(cart.getCouponIds());
                storeSale.setMemberId(cart.getMemberId());
                storeSale.setCouponDiscount(cart.getCouponDiscount());
                storeSale.setPointAmount(cart.getPoint());
                storeSale.setQuantity(cartItem.getNums());
                storeSale.setCostPrice(commodity.getCostPrice());
                storeSale.setSalePrice(commodity.getSalePrice());
                // 利润 = (销售价 - 进价) * 数量
                storeSale.setProfitAmount((commodity.getSalePrice().subtract(commodity.getCostPrice())).multiply(new BigDecimal(cartItem.getNums())));
                // 积分兑换利润为0
                if (PaymentTypeEnum.POINT.getPaymentType().equals(storeSale.getPayType())) {
                    storeSale.setProfitAmount(new BigDecimal(BigInteger.ZERO));
                    storeSale.setPayAmount(new BigDecimal(BigInteger.ZERO));
                    storeSale.setPointAmount(cart.getAmount().intValue());
                }
                storeSaleList.add(storeSale);
            }
        }
        return storeSaleList;
    }


    /**
     * 设置会员消费数据
     *
     * @param cart   cart
     * @param member member
     */
    public void setMemberSale(Cart cart, WeChatMember member) {
        if (!PaymentTypeEnum.POINT.getPaymentType().equals(cart.getPaymentType())) {
            member.setTotalConsumptionAmount(member.getTotalConsumptionAmount().add(cart.getPayAmount()));
        }
        // 优惠金额 = 应收金额 - 实收金额
        BigDecimal discountAmount = cart.getAmount().subtract(cart.getPayAmount());
        member.setTotalDiscountAmount(member.getTotalDiscountAmount().add(discountAmount));
        member.setTotalConsumptionTimes(member.getTotalConsumptionTimes() + 1);
    }

}
